package com.epin.base.plugins;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.Random;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class RedisSequence {

	private final static Logger LOGGER = LoggerFactory.getLogger(RedisSequence.class);

	private final static String DEFAULT_CONFIG_FILE = "/redis.properties";

	private final static String NS_SEPARATOR = ":";

	private static String seqKey;

	private static JedisPool POOL;
	
	public RedisSequence() {
		this(DEFAULT_CONFIG_FILE);
	}
	
	public RedisSequence(String configFile) {
		Properties pro = new Properties();
		InputStream in = null;
		try {
			if (POOL == null) {
				in = RedisSequence.class.getResourceAsStream(configFile);
				pro.load(in);
				JedisPoolConfig config = new JedisPoolConfig();

				String password = pro.getProperty("redis.password");
				String host = pro.getProperty("redis.host");
				String db = pro.getProperty("redis.database");
				// 系统名称
				seqKey = pro.getProperty("redis.seq") != null ? pro.getProperty("redis.seq").toUpperCase(): "SEQ";

				if (!StringUtils.isBlank(password)) {
					POOL = new JedisPool(config, host, Integer.valueOf(pro.getProperty("redis.port")),
							Integer.valueOf(pro.getProperty("redis.timeout")), password, Integer.valueOf(db));
				} else {
					POOL = new JedisPool(config, host, Integer.valueOf(pro.getProperty("redis.port")),
							Integer.valueOf(pro.getProperty("redis.timeout")), null, Integer.valueOf(db));
				}
			}
		} catch (FileNotFoundException e) {
			LOGGER.error("Cannot initial RedisSequenceUtil due to config file not found!");
			POOL = null;
		} catch (Exception e) {
			
			LOGGER.error("Fail initial RedisSequenceUtil due to exception!", e);
			POOL = null;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					LOGGER.error("Fail initial RedisSequenceUtil due to exception!", e);
				}
			}
		}
	}
	
	public RedisSequence(JedisPool pool) {
		RedisSequence.POOL = pool;
	}

	/**
	 * 
	 * @Title: getNumber 
	 * @Description: 根据前缀获取单号, 默认格式如：
	 * P201707180001(prefix+yyyyMMdd+0001) 
	 * @param prefix
	 * @return
	 * 参数说明 @throws
	 */
	public String getNumber(String prefix) {
		String dateStr = formatDate("yyyyMMdd");
		long number = next(prefix, dateStr);

		String numberStr = StringUtils.leftPad(String.valueOf(number), 4, "0");

		return prefix + dateStr + numberStr;
	}

	public String getNumber(String prefix, int padSize) {
		String dateStr = "";
		long number = next(prefix, dateStr);

		String numberStr = StringUtils.leftPad(String.valueOf(number), padSize, "0");

		return prefix + dateStr + numberStr;
	}

	public String getNumber(String prefix, String dateFormat, int padSize) {
		String dateStr = formatDate(dateFormat);
		long number = next(prefix, dateFormat);

		String numberStr = StringUtils.leftPad(String.valueOf(number), padSize, "0");

		return prefix + dateStr + numberStr;
	}

	public Long next(String prefix) {
		return next(prefix, formatDate("yyyyMMdd"));
	}

	public Long next(String prefix, String dateStr) {
		Long next = -1L;
		if (POOL != null) {
			Jedis jedis = POOL.getResource();
			String key = seqKey + NS_SEPARATOR + prefix + dateStr;
			try {
				next = jedis.incr(key);
				jedis.close();
			} catch (Exception e) {
				LOGGER.error("Fail to get next!", e);
			}
		}
		return next;
	}

	private  String formatDate(String dateFormat) {
		String rtn = "";
		if (dateFormat != null && dateFormat.trim().length() > 0) {
			SimpleDateFormat format = new SimpleDateFormat(dateFormat);
			rtn = format.format(new Date());
		}

		return rtn;
	}

	public  void main(String[] args) {
		for (int i = 0; i < 100; i++) {
			Thread t = new UserThread();
			t.start();
		}
	}

	public static class UserThread extends Thread {
		@Override
		public void run() {
			while (true) {
				try {
					System.out.println(Thread.currentThread().getName() + " " + new Date() + " : "
							+ new RedisSequence("/redis.properties").getNumber("TXNSEQ"));
					Random r = new Random();
					Thread.sleep(r.nextInt(100) * 1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

}
